package models

import (
	"crypto/rand"
	"time"

	"github.com/beego/beego/v2/client/orm"
)

// Refund 退款记录模型
type Refund struct {
	BaseModel
	RefundNo       string  `orm:"size(64);unique" json:"refund_no"`        // 退款单号
	OrderNo        string  `orm:"size(64);index" json:"order_no"`          // 关联订单号
	MemberId       int64   `orm:"index" json:"member_id"`                  // 会员ID
	Amount         float64 `orm:"digits(10);decimals(2)" json:"amount"`    // 退款金额
	PaymentChannel string  `orm:"size(20)" json:"payment_channel"`         // 原支付渠道
	TransactionId  string  `orm:"size(64)" json:"transaction_id"`          // 原交易号
	RefundTradeNo  string  `orm:"size(64)" json:"refund_trade_no"`         // 退款交易号
	Reason         string  `orm:"size(255)" json:"reason"`                 // 退款原因
	Remark         string  `orm:"size(255)" json:"remark"`                 // 备注
	Status         string  `orm:"size(20);default(pending)" json:"status"` // 退款状态：pending(待审核), approved(已审核), processing(处理中), success(已完成), rejected(已拒绝), failed(退款失败)
	AuditTime      int64   `orm:"default(0)" json:"audit_time"`            // 审核时间
	AuditorId      int64   `orm:"default(0)" json:"auditor_id"`            // 审核人ID
	CompletionTime int64   `orm:"default(0)" json:"completion_time"`       // 完成时间
}

// TableName 设置表名
func (r *Refund) TableName() string {
	return "ss_refund"
}

// GetRefundById 根据ID获取退款记录
func GetRefundById(id int64) (*Refund, error) {
	refund := &Refund{BaseModel: BaseModel{Id: id}}
	o := orm.NewOrm()
	err := o.Read(refund)
	return refund, err
}

// GetRefundByRefundNo 根据退款单号获取退款记录
func GetRefundByRefundNo(refundNo string) (*Refund, error) {
	refund := &Refund{RefundNo: refundNo}
	o := orm.NewOrm()
	err := o.Read(refund, "RefundNo")
	return refund, err
}

// GetRefundByOrderNo 根据订单号获取退款记录
func GetRefundByOrderNo(orderNo string) (*Refund, error) {
	refund := &Refund{OrderNo: orderNo}
	o := orm.NewOrm()
	err := o.Read(refund, "OrderNo")
	return refund, err
}

// GetRefundList 获取退款记录列表
func GetRefundList(page, pageSize int, filters map[string]interface{}) ([]*Refund, int64, error) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(Refund))

	// 应用过滤条件
	if refundNo, ok := filters["refund_no"].(string); ok && refundNo != "" {
		qs = qs.Filter("refund_no__contains", refundNo)
	}

	if orderNo, ok := filters["order_no"].(string); ok && orderNo != "" {
		qs = qs.Filter("order_no__contains", orderNo)
	}

	if memberId, ok := filters["member_id"].(int64); ok {
		qs = qs.Filter("member_id", memberId)
	}

	if status, ok := filters["status"].(string); ok && status != "" {
		qs = qs.Filter("status", status)
	}

	if username, ok := filters["username"].(string); ok && username != "" {
		// 这里需要关联会员表查询，简化处理，实际可能需要使用原生SQL或其他方式
		// 这里仅作为示例
		members := []*Member{}
		_, err := o.QueryTable(new(Member)).Filter("username__contains", username).All(&members)
		if err == nil && len(members) > 0 {
			memberIds := []int64{}
			for _, member := range members {
				memberIds = append(memberIds, member.Id)
			}
			qs = qs.Filter("member_id__in", memberIds)
		}
	}

	// 时间范围过滤
	if startTime, ok := filters["start_time"].(int64); ok {
		qs = qs.Filter("created_at__gte", startTime)
	}

	if endTime, ok := filters["end_time"].(int64); ok {
		qs = qs.Filter("created_at__lte", endTime)
	}

	// 排除已删除的记录
	qs = qs.Filter("is_deleted", 0)

	// 获取总数
	total, _ := qs.Count()

	// 分页查询
	var refunds []*Refund
	_, err := qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&refunds)

	return refunds, total, err
}

// CreateRefund 创建退款记录
func CreateRefund(refund *Refund) (int64, error) {
	// 生成退款单号
	if refund.RefundNo == "" {
		refund.RefundNo = "RF" + time.Now().Format("20060102150405") + RandomString(6)
	}

	o := orm.NewOrm()
	id, err := o.Insert(refund)
	return id, err
}

// UpdateRefund 更新退款记录
func UpdateRefund(refund *Refund, fields ...string) error {
	o := orm.NewOrm()
	_, err := o.Update(refund, fields...)
	return err
}

// UpdateRefundStatus 更新退款状态
func UpdateRefundStatus(id int64, status string, refundTradeNo string) error {
	o := orm.NewOrm()
	refund := &Refund{BaseModel: BaseModel{Id: id}}
	if err := o.Read(refund); err != nil {
		return err
	}

	refund.Status = status
	refund.RefundTradeNo = refundTradeNo

	// 根据状态设置相应的时间
	now := time.Now().Unix()
	switch status {
	case "approved", "rejected": // 已审核或已拒绝
		refund.AuditTime = now
	case "success": // 已完成
		refund.CompletionTime = now
	}

	_, err := o.Update(refund, "Status", "RefundTradeNo", "AuditTime", "CompletionTime", "UpdatedAt")
	return err
}

// AuditRefund 审核退款
func AuditRefund(id int64, status string, auditorId int64, remark string) error {
	o := orm.NewOrm()
	refund := &Refund{BaseModel: BaseModel{Id: id}}
	if err := o.Read(refund); err != nil {
		return err
	}

	// 只有待审核状态才能审核
	if refund.Status != "pending" {
		return orm.ErrNoRows
	}

	refund.Status = status
	refund.AuditorId = auditorId
	refund.Remark = remark
	refund.AuditTime = time.Now().Unix()

	_, err := o.Update(refund, "Status", "AuditorId", "Remark", "AuditTime", "UpdatedAt")
	return err
}

// GetMemberRefunds 获取会员的退款记录
func GetMemberRefunds(memberId int64, page, pageSize int) ([]*Refund, int64, error) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(Refund)).Filter("member_id", memberId).Filter("is_deleted", 0)

	// 获取总数
	total, _ := qs.Count()

	// 分页查询
	var refunds []*Refund
	_, err := qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&refunds)

	return refunds, total, err
}

// RandomString 生成随机字符串
func RandomString(n int) string {
	const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, n)
	if _, err := rand.Read(b); err != nil {
		return ""
	}
	for i := range b {
		b[i] = letters[int(b[i])%len(letters)]
	}
	return string(b)
}
